#ifndef CLUSTER_METRIC_H
#define CLUSTER_METRIC_H

#include <string>
#include "Cluster.h"
#include "Layering.h"
#include "Accumulator.h"

// types of inter-cluster distance:
struct Cluster_Distance {
    typedef enum {
        AVERAGE,
        SINGLE,
        COMPLETE
    } Type;
};

// cluster representative sets for inter-cluster distance calcs:
struct Representative_Set {
    typedef enum {
        WHOLE,
        EXTERIOR,
        INTERIOR,
        MEDOID
    } Type;
};

class Cluster_Metric {
public:
    Cluster_Metric(Cluster_Distance::Type distance_type,
                   Representative_Set::Type representatives);

    double distance(Cluster *A, Cluster *B);

private:
    Cluster_Distance::Type distance_type;
    Representative_Set::Type representatives;

    void   accumulate_distance   (Cluster *A, Cluster *B,
                                  Accumulator& accum);
    double complete_link_distance(Cluster *A, Cluster *B);
    double single_link_distance  (Cluster *A, Cluster *B);
    double average_link_distance (Cluster *A, Cluster *B);
};

#endif
